package com.wn.sddfp.sms.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.wn.sddfp.sms.config.SmsTemplate;
import com.wn.sddfp.sms.service.ISmsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yellow Docter
 * @date 2024-07-30
 * @desc 蜗牛创想：www.woniuxy.com
 */
@Service
public class SMSServiceImpl implements ISmsService {

    @Autowired
    private SmsTemplate smsTemplate;  //IOC 容器已存在对象 (自动装配 )

    /**
     * StringRedisTemplate  和  RedisTemplate 的区别?
     *    1、RedisTemplate 是  StringRedisTemplate 父类
     *    2、StringRedisTemplate 她的类型 extends RedisTemplate<String, String> 只能是String类型
     *    3、如果是 复杂的类型     RedisTemplate
     *      如果是  字符串的类型   StringRedisTemplate
     */
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Map<String, Object> getCode(String phone) {

        //业务逻辑实现
        //给手机发送验证码
        //RandomUtil.randomNumbers 是hutool 工具类提供的 一个随机字符串的方法
        String code = RandomUtil.randomNumbers(4);

        smsTemplate.sendSms(phone,code);

        HashMap<String,Object> map = new HashMap<>();

        //防止短信轰炸
        String keyCount = "sms:count:" + phone;

        //判断次数
        String count = stringRedisTemplate.opsForValue().get(keyCount);

        if (!StringUtils.isEmpty(count) && Integer.parseInt(count) == 5 ){
            map.put("msg","不能短时间发送太多验证码");
            return map;
        }

        if (stringRedisTemplate.hasKey(keyCount)){
            //存在就 + 1
            stringRedisTemplate.opsForValue().increment(keyCount);
        }else{
            //第一次存储
            stringRedisTemplate.opsForValue().set(keyCount,"1",Duration.ofMinutes(10));
        }
        //给把验证码 存储到redis中
        stringRedisTemplate.opsForValue().set(
                "SMS:" + phone,
                code,
                Duration.ofMinutes(5)
        );
        map.put("code",code);
        map.put("phone",phone);

        return map;
    }
}
